﻿/*!
 * Copyright (c), 上海沃恩信息科技有限公司.
 * All rights reserved.
 * Licensed under BSD (https://www.pittypat.work/bsd.html).
 */

using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

namespace Pittypat.Web
{
    /// <summary>
    /// 向客户端响应一个 <see cref="VirtualStream"/> 对象。
    /// </summary>
    sealed class VirtualStreamMessage : Message
    {
        // 目标数据流
        private VirtualStream stream;

        /// <summary>
        /// 使用要响应的 <see cref="VirtualStream"/> 流初始化 <see cref="VirtualStreamMessage"/> 类的新实例。
        /// </summary>
        /// <param name="stream">要响应的 <see cref="VirtualStream"/> 流。可以为 null，此时不会发送任何数据。</param>
        internal VirtualStreamMessage(VirtualStream stream)
        {
            this.stream = stream;
        }

        /// <summary>
        /// 将当前对象作为 JSON 字符串写入指定的文本流。
        /// </summary>
        /// <param name="writer">目标文本流。</param>
        /// <exception cref="ArgumentNullException">writer 是 null。</exception>
        public override void Write(TextWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }

            if (this.stream == null)
            {
                writer.Write("null");
            }
            else
            {
                ((IJson)this.stream).Write(writer);
            }
        }

        /// <summary>
        /// 通过 WebSocket 发送消息。
        /// </summary>
        /// <param name="progress">异步进度。</param>
        /// <param name="bufferSize">缓冲区的大小，如果小于等于 0，则使用配置文件中 socketDataSize 作为缓冲区尺寸。</param>
        /// <returns>异步任务。</returns>
        internal override Task SendAsync(WebSocketAsyncProgress progress, int bufferSize = 0)
        {
            if (this.stream != null)
            {
                return this.stream.SendAsync(progress, bufferSize);
            }

            return Task.FromResult((object)null);
        }

        /// <summary>
        /// 将文件作为响应内容附加到指定的响应消息。用于 AJAX 请求。
        /// </summary>
        /// <param name="response">目标响应。</param>
        internal override void ToResponseContent(HttpResponseMessage response)
        {
            if (this.stream != null)
            {
                this.stream.ToResponseContent(response);
            }
        }
    }
}
